package com.itany.corejava.code16_反射;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

/**
 * @author 石小俊
 * @date 2023年06月01日 10:16
 */
public class Test03_Constructor {

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        User user = new User();
        Class c = user.getClass();
        // 1.获取当前类中的所有public修改的构造方法
        Constructor[] constructors = c.getConstructors();
        System.out.println(Arrays.toString(constructors));

        // 2.获取当前类中所有的构造方法
        Constructor[] declaredConstructors = c.getDeclaredConstructors();
        System.out.println(Arrays.toString(declaredConstructors));

        // 3.根据传递的方法参数不同,返回对应的由public修饰的构造方法
        // 其方法参数是一个Class类型的可变长参数
        Constructor constructor = c.getConstructor();
        System.out.println(constructor);
        // 由于当前参数为String的构造方法是被private修饰的,无法获取,因此抛出了异常
        // constructor = c.getConstructor(String.class);
        // 获取两个参数的构造方法
        constructor = c.getConstructor(String.class, String.class);
        System.out.println(constructor);

        // 4.根据传递的方法参数不同,返回对应的构造方法
        // 其方法参数是一个Class类型的可变长参数
        Constructor declaredConstructor = c.getDeclaredConstructor(String.class);
        System.out.println(declaredConstructor);


        // 通过反射来调用指定的构造方法创建对应的对象
        User user1 = (User) constructor.newInstance("admin", "123456");
        System.out.println(user1);

        // 由于当前调用的构造方法是被private所修饰的,外部无法访问
        // 因此,此时通过调用构造方法获取对象时,报错
        // 如果想要使用该构造方法去创建对象,必须破坏原有的封装原则,使得private失效
        // setAccessible(true):取消权限控制,使得private失效,破坏原有的封装原则
        declaredConstructor.setAccessible(true);
        User user2 = (User) declaredConstructor.newInstance("alice");
        System.out.println(user2);


    }

}
